"""
简化的数据模型
Simple Data Models

定义系统中使用的核心数据模型：
- 摄像头模型
- WVP设备模型
- AI结果模型
- 用户模型
"""
from dataclasses import dataclass, field
from typing import Optional, Dict, Any, List
from datetime import datetime
from enum import Enum


class CameraStatus(str, Enum):
    """摄像头状态枚举"""
    ONLINE = "online"
    OFFLINE = "offline"
    ERROR = "error"
    MAINTENANCE = "maintenance"


class StreamStatus(str, Enum):
    """流状态枚举"""
    ACTIVE = "active"
    INACTIVE = "inactive"
    CONNECTING = "connecting"
    ERROR = "error"


class UserRole(str, Enum):
    """用户角色枚举"""
    ADMIN = "admin"
    OPERATOR = "operator"
    USER = "user"
    VIEWER = "viewer"


@dataclass
class Camera:
    """摄像头数据模型"""
    id: Optional[int] = None
    name: str = ""
    longitude: float = 0.0
    latitude: float = 0.0
    height: float = 10.0
    location: Optional[str] = None
    rtsp_url: Optional[str] = None
    wvp_device_id: Optional[str] = None
    wvp_channel_id: Optional[str] = None
    description: Optional[str] = None
    ai_enabled: bool = False
    status: CameraStatus = CameraStatus.OFFLINE
    stream_status: StreamStatus = StreamStatus.INACTIVE
    ai_algorithms: Dict[str, Any] = field(default_factory=dict)
    processing_fps: int = 3
    priority_level: int = 5
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    last_frame_time: Optional[datetime] = None
    reconnect_count: int = 0
    last_error: Optional[str] = None
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'id': self.id,
            'name': self.name,
            'longitude': self.longitude,
            'latitude': self.latitude,
            'height': self.height,
            'location': self.location,
            'rtsp_url': self.rtsp_url,
            'wvp_device_id': self.wvp_device_id,
            'wvp_channel_id': self.wvp_channel_id,
            'description': self.description,
            'ai_enabled': self.ai_enabled,
            'status': self.status.value if isinstance(self.status, CameraStatus) else self.status,
            'stream_status': self.stream_status.value if isinstance(self.stream_status, StreamStatus) else self.stream_status,
            'ai_algorithms': self.ai_algorithms,
            'processing_fps': self.processing_fps,
            'priority_level': self.priority_level,
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'updated_at': self.updated_at.isoformat() if self.updated_at else None,
            'last_frame_time': self.last_frame_time.isoformat() if self.last_frame_time else None,
            'reconnect_count': self.reconnect_count,
            'last_error': self.last_error
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'Camera':
        """从字典创建实例"""
        # 处理日期时间字段
        created_at = None
        if data.get('created_at'):
            if isinstance(data['created_at'], str):
                try:
                    created_at = datetime.fromisoformat(data['created_at'].replace('Z', '+00:00'))
                except:
                    created_at = None
            elif isinstance(data['created_at'], datetime):
                created_at = data['created_at']
        
        updated_at = None
        if data.get('updated_at'):
            if isinstance(data['updated_at'], str):
                try:
                    updated_at = datetime.fromisoformat(data['updated_at'].replace('Z', '+00:00'))
                except:
                    updated_at = None
            elif isinstance(data['updated_at'], datetime):
                updated_at = data['updated_at']
        
        last_frame_time = None
        if data.get('last_frame_time'):
            if isinstance(data['last_frame_time'], str):
                try:
                    last_frame_time = datetime.fromisoformat(data['last_frame_time'].replace('Z', '+00:00'))
                except:
                    last_frame_time = None
            elif isinstance(data['last_frame_time'], datetime):
                last_frame_time = data['last_frame_time']
        
        # 处理ai_algorithms字段
        ai_algorithms = data.get('ai_algorithms', {})
        if isinstance(ai_algorithms, str):
            try:
                import json
                ai_algorithms = json.loads(ai_algorithms)
            except:
                ai_algorithms = {}
        
        return cls(
            id=data.get('id'),
            name=data.get('name', ''),
            longitude=float(data.get('longitude', 0.0)),
            latitude=float(data.get('latitude', 0.0)),
            height=float(data.get('height', 10.0)),
            location=data.get('location'),
            rtsp_url=data.get('rtsp_url'),
            wvp_device_id=data.get('wvp_device_id'),
            wvp_channel_id=data.get('wvp_channel_id'),
            description=data.get('description'),
            ai_enabled=bool(data.get('ai_enabled', False)),
            status=CameraStatus(data.get('status', CameraStatus.OFFLINE)),
            stream_status=StreamStatus(data.get('stream_status', StreamStatus.INACTIVE)),
            ai_algorithms=ai_algorithms,
            processing_fps=int(data.get('processing_fps', 3)),
            priority_level=int(data.get('priority_level', 5)),
            created_at=created_at,
            updated_at=updated_at,
            last_frame_time=last_frame_time,
            reconnect_count=int(data.get('reconnect_count', 0)),
            last_error=data.get('last_error')
        )


@dataclass
class WVPDevice:
    """WVP设备数据模型"""
    id: Optional[int] = None
    device_id: str = ""
    device_name: Optional[str] = None
    manufacturer: Optional[str] = None
    model: Optional[str] = None
    firmware: Optional[str] = None
    transport: Optional[str] = None
    stream_mode: Optional[str] = None
    ip: Optional[str] = None
    port: Optional[int] = None
    host_address: Optional[str] = None
    expires: Optional[int] = None
    register_time: Optional[datetime] = None
    keepalive_time: Optional[datetime] = None
    channel_count: int = 0
    status: str = "offline"
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'id': self.id,
            'device_id': self.device_id,
            'device_name': self.device_name,
            'manufacturer': self.manufacturer,
            'model': self.model,
            'firmware': self.firmware,
            'transport': self.transport,
            'stream_mode': self.stream_mode,
            'ip': self.ip,
            'port': self.port,
            'host_address': self.host_address,
            'expires': self.expires,
            'register_time': self.register_time.isoformat() if self.register_time else None,
            'keepalive_time': self.keepalive_time.isoformat() if self.keepalive_time else None,
            'channel_count': self.channel_count,
            'status': self.status,
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'updated_at': self.updated_at.isoformat() if self.updated_at else None
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'WVPDevice':
        """从字典创建实例"""
        # 处理日期时间字段
        def parse_datetime(dt_str):
            if not dt_str:
                return None
            if isinstance(dt_str, str):
                try:
                    return datetime.fromisoformat(dt_str.replace('Z', '+00:00'))
                except:
                    return None
            elif isinstance(dt_str, datetime):
                return dt_str
            return None
        
        return cls(
            id=data.get('id'),
            device_id=data.get('device_id', ''),
            device_name=data.get('device_name'),
            manufacturer=data.get('manufacturer'),
            model=data.get('model'),
            firmware=data.get('firmware'),
            transport=data.get('transport'),
            stream_mode=data.get('stream_mode'),
            ip=data.get('ip'),
            port=data.get('port'),
            host_address=data.get('host_address'),
            expires=data.get('expires'),
            register_time=parse_datetime(data.get('register_time')),
            keepalive_time=parse_datetime(data.get('keepalive_time')),
            channel_count=int(data.get('channel_count', 0)),
            status=data.get('status', 'offline'),
            created_at=parse_datetime(data.get('created_at')),
            updated_at=parse_datetime(data.get('updated_at'))
        )


@dataclass
class WVPChannel:
    """WVP通道数据模型"""
    id: Optional[int] = None
    device_id: str = ""
    channel_id: str = ""
    channel_name: Optional[str] = None
    manufacturer: Optional[str] = None
    model: Optional[str] = None
    owner: Optional[str] = None
    civil_code: Optional[str] = None
    block: Optional[str] = None
    address: Optional[str] = None
    parental: int = 0
    parent_id: Optional[str] = None
    safety_way: int = 0
    register_way: int = 1
    cert_num: Optional[str] = None
    certifiable: int = 0
    err_code: int = 0
    end_time: Optional[datetime] = None
    secrecy: Optional[str] = None
    ip_address: Optional[str] = None
    port: Optional[int] = None
    password: Optional[str] = None
    ptz_type: int = 0
    status: str = "offline"
    longitude: float = 0.0
    latitude: float = 0.0
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'id': self.id,
            'device_id': self.device_id,
            'channel_id': self.channel_id,
            'channel_name': self.channel_name,
            'manufacturer': self.manufacturer,
            'model': self.model,
            'owner': self.owner,
            'civil_code': self.civil_code,
            'block': self.block,
            'address': self.address,
            'parental': self.parental,
            'parent_id': self.parent_id,
            'safety_way': self.safety_way,
            'register_way': self.register_way,
            'cert_num': self.cert_num,
            'certifiable': self.certifiable,
            'err_code': self.err_code,
            'end_time': self.end_time.isoformat() if self.end_time else None,
            'secrecy': self.secrecy,
            'ip_address': self.ip_address,
            'port': self.port,
            'password': self.password,
            'ptz_type': self.ptz_type,
            'status': self.status,
            'longitude': self.longitude,
            'latitude': self.latitude,
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'updated_at': self.updated_at.isoformat() if self.updated_at else None
        }


@dataclass
class AIResult:
    """AI分析结果数据模型"""
    id: Optional[int] = None
    camera_id: int = 0
    algorithm: str = ""
    result_data: Dict[str, Any] = field(default_factory=dict)
    confidence: Optional[float] = None
    processing_time: Optional[float] = None
    created_at: Optional[datetime] = None
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'id': self.id,
            'camera_id': self.camera_id,
            'algorithm': self.algorithm,
            'result_data': self.result_data,
            'confidence': self.confidence,
            'processing_time': self.processing_time,
            'created_at': self.created_at.isoformat() if self.created_at else None
        }


@dataclass
class User:
    """用户数据模型"""
    id: Optional[int] = None
    username: str = ""
    password_hash: str = ""
    email: Optional[str] = None
    full_name: Optional[str] = None
    role: UserRole = UserRole.USER
    is_active: bool = True
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    last_login: Optional[datetime] = None
    
    def to_dict(self, include_password: bool = False) -> Dict[str, Any]:
        """转换为字典"""
        data = {
            'id': self.id,
            'username': self.username,
            'email': self.email,
            'full_name': self.full_name,
            'role': self.role.value if isinstance(self.role, UserRole) else self.role,
            'is_active': self.is_active,
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'updated_at': self.updated_at.isoformat() if self.updated_at else None,
            'last_login': self.last_login.isoformat() if self.last_login else None
        }
        
        if include_password:
            data['password_hash'] = self.password_hash
        
        return data


@dataclass
class SystemConfig:
    """系统配置数据模型"""
    id: Optional[int] = None
    config_key: str = ""
    config_value: Optional[str] = None
    config_type: str = "string"
    description: Optional[str] = None
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'id': self.id,
            'config_key': self.config_key,
            'config_value': self.config_value,
            'config_type': self.config_type,
            'description': self.description,
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'updated_at': self.updated_at.isoformat() if self.updated_at else None
        }
    
    def get_typed_value(self) -> Any:
        """获取类型化的配置值"""
        if not self.config_value:
            return None
        
        try:
            if self.config_type == "int":
                return int(self.config_value)
            elif self.config_type == "float":
                return float(self.config_value)
            elif self.config_type == "bool":
                return self.config_value.lower() in ('true', '1', 'yes', 'on')
            elif self.config_type == "json":
                import json
                return json.loads(self.config_value)
            else:  # string
                return self.config_value
        except (ValueError, TypeError):
            return self.config_value


# 数据库查询结果分页模型
@dataclass
class PageResult:
    """分页结果模型"""
    items: List[Any] = field(default_factory=list)
    total: int = 0
    page: int = 1
    size: int = 10
    pages: int = 0
    
    def __post_init__(self):
        """计算总页数"""
        if self.size > 0:
            self.pages = (self.total + self.size - 1) // self.size
        else:
            self.pages = 0
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'items': [item.to_dict() if hasattr(item, 'to_dict') else item for item in self.items],
            'total': self.total,
            'page': self.page,
            'size': self.size,
            'pages': self.pages
        }


# 数据库操作结果模型
@dataclass
class OperationResult:
    """操作结果模型"""
    success: bool = False
    message: str = ""
    data: Any = None
    error_code: Optional[str] = None
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        result = {
            'success': self.success,
            'message': self.message,
            'error_code': self.error_code
        }
        
        if self.data is not None:
            if hasattr(self.data, 'to_dict'):
                result['data'] = self.data.to_dict()
            else:
                result['data'] = self.data
        
        return result